﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Drawing;
using System.Drawing.Imaging;
using System.Web.Mvc;
using System.IO;
using QiuShiBaiKe.Model;
using System.Text;

namespace QiuShiBaiKe.Web
{
    public static class WebHelper
    {
        public const string VALIDCODE = "VALIDCODE";

        /// <summary>
        /// 把验证码valideCode保存到Sessioin中
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="validCode"></param>
        public static void SaveValidCode(HttpContextBase ctx,string validCode)
        {
            ctx.Session[VALIDCODE] = validCode;
        }

        /// <summary>
        /// 检查用户输入的validCode是否和服务器Sessioin中保存的验证码是否一致
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="validCode"></param>
        /// <returns></returns>
        public static bool IsValidCodeOK(HttpContextBase ctx, string validCode)
        {
            string serverValidCode = (string)ctx.Session[VALIDCODE];
            return String.Equals(validCode, serverValidCode, StringComparison.CurrentCultureIgnoreCase);
        }

        /// <summary>
        /// 重置服务器端保存的验证码，一般用于验证码错误之后的重新刷新密码，避免重复请求暴力破解
        /// </summary>
        /// <param name="ctx"></param>
        public static void ResetValidCode(HttpContextBase ctx)
        {
            string validCode = GenerateValidCode();
            SaveValidCode(ctx, validCode);

        }

        /// <summary>
        /// 生成一个验证码图片
        /// </summary>
        /// <param name="validCode">生成的验证码</param>
        /// <returns>图片的JPEG格式的二进制数据</returns>
        public static byte[] CreateValidCode(out string validCode)
        {
            //常用汉字
            validCode = GenerateValidCode();

            using (Bitmap bmp = new Bitmap(100, 30))
            using (Graphics g = Graphics.FromImage(bmp))
            using (Font font = new Font(new FontFamily("宋体"), 18))
            using (MemoryStream ms = new MemoryStream())
            {
                g.Clear(Color.Yellow);
                //画汉字。1000,9999。E1C2。Guid.NewGuid().ToString()，取后四位(X)
                //"如鹏网最牛中华人民共和国"
                g.DrawString(validCode, font, Brushes.Red, new PointF(0, 0));
                Random rand = new Random();
                for (int i = 0; i < 500; i++)//画上500个随机的点
                {
                    int x = rand.Next(0, 100);
                    int y = rand.Next(0, 30);
                    g.DrawLine(Pens.Red, x, y, x, y);//画一个点
                }
                bmp.Save(ms, ImageFormat.Jpeg);
                ms.Position = 0;
                return ms.ToArray();
            }
        }

        /// <summary>
        /// 重新生成一个随机的四位验证码
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GenerateValidCode()
        {
            //常用汉字
            string cyhz = "人口手大小多少上中下男女天地会反清复明杨中科小宝双儿命名空间语现在明天来多个的我山东河北南固安北京南昌东海西安是沙河高教园学"
                + "木禾上下土个八入大天人火文六七儿九无口日中了子门月不开四五目耳头米见白田电也长山出飞马鸟云公车牛羊小少巾牙尺毛又心手水广升足"
                + "走方半巴业本平书自已东西回片皮生里果几用鱼今正雨两瓜衣来年左右万百丁齐冬说友话春朋高你绿们花红草爷亲节的岁行古处声知多忙洗真认父扫"
                + "母爸写全完关家看笑着兴画会妈合奶放午收女气太早去亮和李语秀千香听远唱定连向以更后意主总先起干明赶净同专工才级队蚂蚁前房空网诗黄林闭"
                + "童立是我朵叶美机她过他时送让吗往吧得虫很河借姐呢呀哪谁凉怕量跟最园脸因阳为光可法石找办许别那到都吓叫再做象点像照沙海桥军竹苗井面乡"
                + "忘想念王这从进边道贝男原爱虾跑吹乐地老快师短淡对热冷情拉活把种给吃练学习非苦常问伴间共伙汽分要没孩位选北湖南秋江只帮星请雪就球跳玩"
                + "桃树刚兰座各带坐急名发成动晚新有么在变什条";
            String yzm = "";
            Random rand = new Random();
            for (int i = 0; i < 4; i++)
            {
                int index = rand.Next(0, cyhz.Length);
                yzm += cyhz[index];//yzm=yzm+cyhz[index]
            }
            return yzm;
        }

        public const string LOGINEDUSER = "LOGINEDUSER";

        /// <summary>
        /// 设置当前登陆用户到当前Session
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="loginedUser"></param>
        public static void SaveLoginedUser(HttpContextBase ctx, User loginedUser)
        {
            ctx.Session[LOGINEDUSER] = loginedUser;
        }

        /// <summary>
        /// 得到当前登录的用户
        /// </summary>
        /// <param name="ctx"></param>
        /// <returns>当前登陆用户对象，如果没有登录，则为null</returns>
        public static User GetLoginedUser(HttpContextBase ctx)
        {
            return (User)ctx.Session[LOGINEDUSER];
        }      

        /// <summary>
        /// 得到一个包含Json信息的JsonResult
        /// </summary>
        /// <param name="isOK">服务器处理是否成功</param>
        /// <param name="msg">报错消息</param>
        /// <param name="nextUrl">下个要访问的地址</param>
        /// <param name="data">携带的额外信息</param>
        /// <returns></returns>
        public static JsonResult GetJsonResult(bool isOK, string msg, string nextUrl=null,object data=null)
        {
            var jsonObj = new { isOK = isOK, msg = msg, nextUrl = nextUrl, data = data };
            return new JsonResult
	        {
                Data = jsonObj
	        };
        }

        /// <summary>
        /// 得到“***必须填写”的消息
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static JsonResult GetValidationMsg_Empty(string name)
        {
            return GetJsonResult(false,name+"必须填！");
        }

        public const string LOGIN_DESTINATION_URL = "LOGINDESTINATIONURL";
        /// <summary>
        /// 设置登陆后要跳转到的页面
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="url"></param>
        public static void SetLoginDestinationUrl(HttpContextBase ctx, string url)
        {
            ctx.Session[LOGIN_DESTINATION_URL] = url;
        }

        /// <summary>
        /// 把当前请求的Url设置为“登陆后要跳转到的页面”
        /// </summary>
        /// <param name="ctx"></param>
        public static void SetLoginDestinationUrl(HttpContextBase ctx)
        {
            string url = ctx.Request.RawUrl;
            SetLoginDestinationUrl(ctx, url);
        }

        /// <summary>
        /// 获得登陆后要跳转到的页面
        /// </summary>
        /// <param name="ctx"></param>
        /// <returns></returns>
        public static string GetLoginDestinationUrl(HttpContextBase ctx)
        {
            string url = (string)ctx.Session[LOGIN_DESTINATION_URL];
            return url??"/Home/Index";//如果为空，则跳转到首页
        }

        /// <summary>
        /// 绘制页面Html代码
        /// </summary>
        /// <param name="urlFormat">页码链接格式，页码的占位符为{pageIndex}，比如/Message/Page/{pageIndex}</param>
        /// <param name="pageIndex">当前页码，从1开始</param>
        /// <param name="totalCount">总数据条数</param>
        /// <param name="pageSize">每一页显示多少数据</param>
        /// <returns></returns>
        public static HtmlString Pager(string urlFormat, int pageIndex, 
            int totalCount, int pageSize=10)
        {
            StringBuilder sbHTML = new StringBuilder();
            int pageCount = (int)Math.Ceiling(totalCount * 1.0 / pageSize);//一共显示多少页
            int startPageIndex = Math.Max(1,pageIndex-5);//不会一下子把所有页码都显示出来，在当前页码前再最多显示5个
            int endPageIndex = Math.Min(pageCount, startPageIndex + 10-1);//一共最多显示10个页码
            for (int i = startPageIndex; i <= endPageIndex; i++)
            {
                sbHTML.Append("<a href='").Append(urlFormat.Replace("{pageIndex}", i.ToString())).Append("'>").Append(i)
                    .Append("</a>");
            }
            return new HtmlString(sbHTML.ToString());
        }

        private const string DBCONTEXT = "DBCONTEXT";

        /// <summary>
        /// 创建DbContext，并且保存到HttpContext
        /// </summary>
        public static void CreateDbContext()
        {
            QiuShiBaiKe.Model.QiuShiBaiKeDBEntities entities = new QiuShiBaiKeDBEntities();
            HttpContext.Current.Items[DBCONTEXT] = entities;
        }

        /// <summary>
        /// 获得本次请求相关的DbContext
        /// </summary>
        public static QiuShiBaiKe.Model.QiuShiBaiKeDBEntities DbContext
        {
            get
            {
                return (QiuShiBaiKe.Model.QiuShiBaiKeDBEntities)HttpContext.Current.Items[DBCONTEXT];
            }
        }

        /// <summary>
        /// 销毁DbContext
        /// </summary>
        public static void FinishDbContext()
        {
            using (DbContext)
            {
                DbContext.SaveChanges();
            }
        }
    }
}